package ${packageName}.tenant;

import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.toolkit.TableInfoHelper;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * MyBatis-Plus 多租户处理器。
 */
@Component
public class TenantLineHandlerImpl implements TenantLineHandler {

    private static final String DEFAULT_TENANT_COLUMN = "${tenantColumn!'tenant_id'}";
    private final Map<String, Boolean> tableTenantCache = new ConcurrentHashMap<>();

    @Override
    public Expression getTenantId() {
        String tenantId = TenantContext.getTenantId();
        if (!StringUtils.hasText(tenantId)) {
            tenantId = "${securityDefaultTenant}";
        }
        return new StringValue(tenantId);
    }

    @Override
    public boolean ignoreTable(String tableName) {
        if (!StringUtils.hasText(tableName)) {
            return true;
        }
        return !supportsTenant(tableName);
    }

    @Override
    public String getTenantIdColumn() {
        return DEFAULT_TENANT_COLUMN;
    }

    private boolean supportsTenant(String tableName) {
        return tableTenantCache.computeIfAbsent(tableName.toLowerCase(Locale.ROOT), key ->
            TableInfoHelper.getTableInfos().stream()
                .filter(info -> equalsIgnoreCase(info.getTableName(), tableName))
                .findFirst()
                .map(this::hasTenantField)
                .orElse(false)
        );
    }

    private boolean hasTenantField(TableInfo info) {
        if (equalsIgnoreCase(info.getKeyColumn(), DEFAULT_TENANT_COLUMN)) {
            return true;
        }
        for (TableFieldInfo field : info.getFieldList()) {
            if (equalsIgnoreCase(field.getColumn(), DEFAULT_TENANT_COLUMN)
                || equalsIgnoreCase(field.getProperty(), "tenantId")
                || equalsIgnoreCase(field.getProperty(), "tenantCode")) {
                return true;
            }
        }
        return false;
    }

    private boolean equalsIgnoreCase(String left, String right) {
        if (left == null || right == null) {
            return false;
        }
        return left.equalsIgnoreCase(right);
    }
}
